import express from 'express';
import { body, validationResult, query, param } from 'express-validator';
import { RedeemCode, Domain, Expert } from '../models/index.js';
import { authenticateAdmin } from '../middleware/auth.js';
import { catchAsync, BusinessError, NotFoundError } from '../middleware/errorHandler.js';
import { success, paginated } from '../utils/response.js';
import { Sequelize } from 'sequelize';

const router = express.Router();

// 手机端用户接口已移至 /api/mobile/redeem-codes/

// 管理员接口 - 获取兑换码列表
router.get('/admin/list',
  authenticateAdmin,
  [
    query('page').optional().isInt({ min: 1 }).withMessage('页码必须是正整数'),
    query('limit').optional().isInt({ min: 1, max: 100 }).withMessage('每页数量必须在1-100之间'),
    query('quota_type').optional().isIn(['general', 'domain', 'expert']).withMessage('额度类型参数无效'),
    query('is_used').optional().isBoolean().withMessage('使用状态参数必须是布尔值'),
    query('created_by').optional().isInt({ min: 1 }).withMessage('创建人ID必须是正整数'),
    query('batch').optional().isString().withMessage('批次参数必须是字符串')
  ],
  catchAsync(async (req, res) => {
    const { page = 1, limit = 20, quota_type, is_used, created_by, batch } = req.query;
    
    const result = await RedeemCode.getList({
      page: parseInt(page),
      limit: parseInt(limit),
      quotaType: quota_type,
      isUsed: is_used !== undefined ? is_used === 'true' : undefined,
      createdBy: created_by ? parseInt(created_by) : undefined,
      batch: batch
    });
    
    res.json(paginated(result.rows, {
      page: parseInt(page),
      limit: parseInt(limit),
      total: result.count,
      pages: Math.ceil(result.count / parseInt(limit))
    }, '获取兑换码列表成功'));
  })
);

// 管理员接口 - 获取批次列表
router.get('/admin/batches',
  authenticateAdmin,
  catchAsync(async (req, res) => {
    const batches = await RedeemCode.getBatchList();

    res.json(success(
      batches.map(item => item.batch),
      '获取批次列表成功'
    ));
  })
);

// 管理员接口 - 创建兑换码
router.post('/admin/create',
  authenticateAdmin,
  [
    body('quota_type')
      .isIn(['general', 'domain', 'expert'])
      .withMessage('额度类型必须是general、domain或expert'),
    body('target_id')
      .optional()
      .isInt({ min: 1 })
      .withMessage('目标ID必须是正整数'),
    body('redeem_count')
      .isInt({ min: 1, max: 1000 })
      .withMessage('可兑换次数必须在1-1000之间'),
    body('expires_at')
      .optional()
      .isISO8601()
      .withMessage('过期时间格式不正确'),
    body('batch')
      .optional()
      .isString()
      .isLength({ max: 50 })
      .withMessage('批次标识长度不能超过50个字符'),

  ],
  catchAsync(async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      throw new BusinessError('参数验证失败', errors.array());
    }

    const { quota_type, target_id, redeem_count, expires_at, batch } = req.body;
    const adminId = req.admin.id;

    // 验证目标ID的有效性
    if (quota_type === 'domain' && target_id) {
      const domain = await Domain.findByPk(target_id);
      if (!domain) {
        throw new BusinessError('指定的领域不存在');
      }
    } else if (quota_type === 'expert' && target_id) {
      const expert = await Expert.findByPk(target_id);
      if (!expert) {
        throw new BusinessError('指定的专家不存在');
      }
    }

    // 创建兑换码（系统自动生成兑换码）
    const redeemCode = await RedeemCode.createCode({
      quota_type,
      target_id: quota_type === 'general' ? null : target_id,
      redeem_count,
      expires_at: expires_at ? new Date(expires_at) : null,
      batch: batch || null, // 如果没有提供批次，留空
      created_by: adminId
    });
    
    res.json(success({
      redeemCode
    }, '兑换码创建成功'));
  })
);

// 管理员接口 - 批量创建兑换码
router.post('/admin/batch-create',
  authenticateAdmin,
  [
    body('quota_type')
      .isIn(['general', 'domain', 'expert'])
      .withMessage('额度类型必须是general、domain或expert'),
    body('target_id')
      .optional()
      .isInt({ min: 1 })
      .withMessage('目标ID必须是正整数'),
    body('redeem_count')
      .isInt({ min: 1, max: 1000 })
      .withMessage('可兑换次数必须在1-1000之间'),
    body('count')
      .isInt({ min: 1, max: 1000 })
      .withMessage('生成数量必须在1-1000之间'),
    body('expires_at')
      .optional()
      .isISO8601()
      .withMessage('过期时间格式不正确'),
    body('batch')
      .optional()
      .isString()
      .isLength({ max: 50 })
      .withMessage('批次标识长度不能超过50个字符')
  ],
  catchAsync(async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      throw new BusinessError('参数验证失败', errors.array());
    }

    const { quota_type, target_id, redeem_count, count, expires_at, batch } = req.body;
    const adminId = req.admin.id;
    
    // 验证目标ID的有效性
    if (quota_type === 'domain' && target_id) {
      const domain = await Domain.findByPk(target_id);
      if (!domain) {
        throw new BusinessError('指定的领域不存在');
      }
    } else if (quota_type === 'expert' && target_id) {
      const expert = await Expert.findByPk(target_id);
      if (!expert) {
        throw new BusinessError('指定的专家不存在');
      }
    }
    
    // 批量创建兑换码
    const redeemCodes = await RedeemCode.createBatch({
      quota_type,
      target_id: quota_type === 'general' ? null : target_id,
      redeem_count,
      count,
      expires_at: expires_at ? new Date(expires_at) : null,
      batch: batch || null, // 如果没有提供批次，留空
      created_by: adminId
    });
    
    res.json(success({
      redeemCodes,
      count
    }, '批量创建兑换码成功'));
  })
);

// 管理员接口 - 获取兑换码统计数据
router.get('/admin/stats',
  authenticateAdmin,
  catchAsync(async (req, res) => {
    // 无论是否有数据，都返回统计结果，没有数据时各项为0
    try {
      // 获取总数
      const total = await RedeemCode.count();

      // 获取未使用数量
      const unused = await RedeemCode.count({
        where: {
          is_used: false,
          [Sequelize.Op.or]: [
            { expires_at: null },
            { expires_at: { [Sequelize.Op.gt]: new Date() } }
          ]
        }
      });

      // 获取已使用数量
      const used = await RedeemCode.count({
        where: { is_used: true }
      });

      // 获取已过期数量
      const expired = await RedeemCode.count({
        where: {
          is_used: false,
          expires_at: { [Sequelize.Op.lte]: new Date() }
        }
      });

      res.json(success({
        total,
        unused,
        used,
        expired
      }, '获取兑换码统计成功'));
    } catch (error) {
      console.error('获取兑换码统计数据失败:', error);
      // 即使出错也返回全为0的结果，而不是错误
      res.json(success({
        total: 0,
        unused: 0,
        used: 0,
        expired: 0
      }, '获取兑换码统计成功'));
    }
  })
);

// 管理员接口 - 获取兑换码详情
router.get('/admin/:id',
  authenticateAdmin,
  [
    param('id').isInt({ min: 1 }).withMessage('兑换码ID必须是正整数')
  ],
  catchAsync(async (req, res) => {
    const { id } = req.params;

    const redeemCode = await RedeemCode.findByPk(id, {
      include: [
        { association: 'domain', attributes: ['id', 'name'] },
        { association: 'expert', attributes: ['id', 'nickname'] },
        { association: 'creator', attributes: ['id', 'username'] }
      ]
    });

    if (!redeemCode) {
      throw new NotFoundError('兑换码不存在-详情');
    }

    res.json(success({
      redeemCode
    }, '获取兑换码详情成功'));
  })
);

// 管理员接口 - 删除兑换码
router.delete('/admin/:id',
  authenticateAdmin,
  [
    param('id').isInt({ min: 1 }).withMessage('兑换码ID必须是正整数')
  ],
  catchAsync(async (req, res) => {
    const { id } = req.params;

    const redeemCode = await RedeemCode.findByPk(id);
    if (!redeemCode) {
      throw new NotFoundError('兑换码不存在-删除');
    }

    if (redeemCode.is_used) {
      throw new BusinessError('已使用的兑换码不能删除');
    }

    await redeemCode.destroy();

    res.json(success(null, '兑换码删除成功'));
  })
);

export default router;
